#include "Shape.h"

Shape::Shape():m_dirX(0), m_dirY(0) ,m_sumDirX (0), m_sumDirY(0) , m_printWithSplit(0),
						m_timesDirXChanged(0), m_timesDirYChanged(0){};

bool Shape::legalDirXDirY ( double dirX, double dirY) const
{
	if (abs(dirX) > 1 || abs(dirY) > 1)
	{
		cerr << "Error: a direction must be between -1 to 1 only" << endl;
		return false;
	}

	return true;
}

void Shape::set(Point p1, double dirX, double dirY)
{	
	m_point = p1;
	m_dirX = dirX;
	m_dirY = dirY;
	m_printWithSplit = this->isInBorders();
}

bool Shape::setDirection(double dirX, double dirY)
{
	if (legalDirXDirY(dirX, dirY))
	{
		m_dirX = dirX;
		m_dirY = dirY;
		return true;
	}

	return false;
}

void Shape::updatePrintWithSplit ()
{
	m_printWithSplit = isInBorders();
}

void Shape::initSum()
{
	this->m_sumDirX=0;
	this->m_sumDirY=0;
}

void Shape::saveOriginalDir()
{
	m_originalDirX = m_dirX;
	m_originalDirY = m_dirY;
}

void Shape::restoreOriginalDir()
{
	m_dirX = m_originalDirX;
	m_dirY = m_originalDirY;
}

bool Shape::writeToText (ofstream &file) 
{
	//write typeID
	string typeID = getTypeId ();
	file << typeID << " " ;
	//write shape's datamembers
	file << this->getDirX() << ' ';
	file << this->getDirY() << ' ';
	file << this->getXPoint() << ' ';
	file << this->getYPoint() << ' ';
	file << this->getPrintWithSplit() << ' ';
	//
	return true;

}

bool Shape::writeToBin (ofstream &file) 
{
	//write typeID
	string typeID = getTypeId ();
	//const char * str;
	int len = typeID.length();
	//str = typeID.c_str();
	//int sizeOfType = sizeof(typeID);
	file.write(reinterpret_cast<char*>(&len), sizeof(int));
	file.write(reinterpret_cast<char*>(&typeID[0]), len);
	//file.write(reinterpret_cast<char*>(&typeID), len*sizeof(char));

	//write shape's datamembers
	double dirX = this->getDirX();
	double dirY = this->getDirY();
	int xPoint = this->getXPoint();
	int yPoint = this->getYPoint();
	bool printWithSplit = this->getPrintWithSplit();

	file.write(reinterpret_cast<char*>( &dirX ), sizeof(double));
	file.write(reinterpret_cast<char*>( &dirY ), sizeof(double));
	file.write(reinterpret_cast<char*>( &xPoint ), sizeof(int));
	file.write(reinterpret_cast<char*>( &yPoint ), sizeof(int));
	file.write(reinterpret_cast<char*>( &printWithSplit ), sizeof(bool));
	//
	return true;

}

const char * Shape::getTypeId ()
{
	// Get the typeid of yourself
	// (which is one of the deriveds).
	const char * type = typeid(*this).name();

	// We are worried that the compiler we
	// use writes the word 'class' before the
	// class, so we want to deal with it properly
	const char * blankPos = strchr(type , ' ');
	if(blankPos!=0)
		type = blankPos + 1;

	// Now save it to file...
	// (using the great MyString class)
	return type;
}

bool Shape::readFromText (ifstream &file)
{
	int newPointX, newPointY;
	double newDirX, newDirY;
	bool newPrintWithSplit;

	//read shape's datamembers
	file >> newDirX;
	file >> newDirY;
	file >> newPointX;
	file >> newPointY;
	file >> newPrintWithSplit;
	//

	this->set (Point (newPointX, newPointY), newDirX, newDirY);
	if (newPrintWithSplit)
		this->updatePrintWithSplit();
	
	return true;
}

bool Shape::readFromBin (ifstream &file)
{
	int newPointX, newPointY;
	double newDirX, newDirY;
	bool newPrintWithSplit;

	//read shape's datamembers
	file.read(reinterpret_cast<char*>( &newDirX ), sizeof(double));
	file.read(reinterpret_cast<char*>( &newDirY ), sizeof(double));
	file.read(reinterpret_cast<char*>( &newPointX ), sizeof(int));
	file.read(reinterpret_cast<char*>( &newPointY ), sizeof(int));
	file.read(reinterpret_cast<char*>( &newPrintWithSplit ), sizeof(bool));
	//

	this->set (Point (newPointX, newPointY), newDirX, newDirY);
	if (newPrintWithSplit)
		this->updatePrintWithSplit();
	
	return true;
}